package com.icloud.cer.rest.util;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.icloud.cer.rest.msg.bean.ClientView;


public class ConnectorManager {
	private static final Logger log = LoggerFactory.getLogger(ConnectorManager.class);
	
	private ConcurrentHashMap<Long, ClientView> registedClients = new ConcurrentHashMap<Long, ClientView>();
	private ConcurrentHashMap<Long, IoSession> sessionMap = new ConcurrentHashMap<Long, IoSession>();
	private ConcurrentHashMap<Long, AtomicInteger> taskCountMap = new ConcurrentHashMap<Long, AtomicInteger>();
	
	public void addClient(long sessionId, String id, String name,InetSocketAddress inetSocketAddr) {
		ClientView clientView = new ClientView();
		clientView.setEncryptorId(id);
		clientView.setEncryptorName(name);
		clientView.setInetSocketAddr(inetSocketAddr);
		clientView.setIp(inetSocketAddr.getAddress().getHostAddress());
		clientView.setPort(inetSocketAddr.getPort());
		registedClients.put(sessionId, clientView);
		log.info("新增客户端：" + clientView + " 客户端数量：" + getClientCount());
	}
	
	public List<ClientView> getAllClient() {
		List<ClientView>  cList= new ArrayList<ClientView>();
		cList.addAll(registedClients.values());
		return cList;
	}
	
	public void updateClient(long sessionId, int status) {
		ClientView cv = registedClients.get(sessionId);
		if(cv == null) {
			log.error("更新加密机状态失败");
			return;
		}
		log.debug("加密机id：" + cv.getEncryptorId() + ",更新状态：" + status);
		cv.setStatus(status);
	}
	
	public IoSession getSessionByEncryptorId(String encryptorId) {
		if(registedClients.isEmpty()) {
			return null;
		}
		Long sessionId = null;
		for(Entry<Long, ClientView> entry : registedClients.entrySet()) {
			ClientView cv = entry.getValue();
			if(encryptorId.equals(cv.getEncryptorId())) {
				sessionId =  entry.getKey();
			}
		}
		if(sessionId == null) {
			return null;
		}
		return sessionMap.get(sessionId);
	}
	
	public ConcurrentHashMap<Long, ClientView> getClientAddr() {
		return registedClients;
	}
	
	public boolean hasClient() {
		return registedClients.isEmpty();
	}
	
	public int getClientCount() {
		return registedClients.size();
	}
	
	public InetSocketAddress getClientAddr(long key) {
		ClientView clientView = registedClients.get(key);
		if(clientView == null) {
			return null;
		}
		return clientView.getInetSocketAddr();
	}
	
	public ClientView getClientView(long key) {
		return registedClients.get(key);
	}
	
	public ClientView removeClient(Long key) {
		ClientView old = registedClients.get(key);
		ClientView addr = registedClients.remove(key);
		if(addr != null) {
			log.warn("移除客户端:" + old + " 客户端数量:" + getClientCount());
			return addr;
		} 
		return null;
	}
	
	
	public void addSession(long sessionId, IoSession session) {
		sessionMap.put(sessionId, session);
		log.info("add session：" + session + " Session数量：" + getClientCount());
		
	}
	
	public ConcurrentHashMap<Long, IoSession> getSessionMap() {
		return sessionMap;
	}
	
	public List<IoSession> getAllSessions() {
		List<IoSession> sessions = new ArrayList<IoSession>();
		sessions.addAll(sessionMap.values());
		return sessions;
	}
	
	public boolean hasSession() {
		return sessionMap.isEmpty();
	}
	
	public int getSessionCount() {
		return sessionMap.size();
	}
	
	public IoSession getSession(long key) {
		return sessionMap.get(key);
	}
	
	public IoSession removeSession(Long key) {
		IoSession old = sessionMap.get(key);
		IoSession session = sessionMap.remove(key);
		if(session != null) {
			log.warn("移除Session:" + old + " Session数量:" + getClientCount());
			old.close(true);
			return session;
		} 
		return session;
	}
	
	public Integer putTask(Long sessionId) {
		AtomicInteger count = taskCountMap.get(sessionId);
		if(count == null) {
			count = new AtomicInteger(0);
			taskCountMap.put(sessionId, count);
		}
		return count.incrementAndGet();
	}
	
	public Integer popTask(Long sessionId) {
		AtomicInteger count = taskCountMap.get(sessionId);
		if(count == null) {
			count = new AtomicInteger(0);
			taskCountMap.put(sessionId, count);
			return count.get();
		}
		if(count.get() == 0) {
			return count.get();
		}
		return count.decrementAndGet();
	}
	
	public IoSession getIdleSession() {
		if(sessionMap.isEmpty()) {
			log.info("Not found session in sessionMap.");
			return null;
		}
		IoSession session = null;
//		Integer min = Integer.MAX_VALUE;
		for (Entry<Long, IoSession> entry : sessionMap.entrySet()) {
			Long sessionId = entry.getKey();
			IoSession value = entry.getValue();
			AtomicInteger ai = taskCountMap.get(sessionId);
			if(value.isConnected()) {
				if(ai == null) {
					return value;
				}
				Integer count = ai.get();
				//一次只能处理一个任务，没有任务的时候，才可以接收任务
				if(count == 0) {
					return value;
				}
//				if(count < min) {
//					min = count;
//					session = value;
//				}
			}
		}
		return session;
	}
	
	public ConcurrentHashMap<Long, AtomicInteger> getTaskCountMap() {
		return taskCountMap;
	}
	
}
